package runtimeData

import (
	"JVM/Jvmgo/GoToJVM/runtimeData/heap"
)

/*
栈帧，Java中每个方法被调用都会创建一个新帧用于存储数据
*/

type Frame struct {
	lower        *Frame        //  指向下一节点指针
	localVars    LocalVars     // 保存局部变量指针
	operandStack *OperandStack // 保存操作数栈指针
	thread       *Thread
	method       *heap.Method
	nextPC       int //当前命令调用完成后的下一个命令
}

func newFrame(thread *Thread, method *heap.Method) *Frame {
	return &Frame{
		thread:       thread,
		method:       method,
		localVars:    newLocalVars(method.MaxLocals()),
		operandStack: newOperandStack(method.MaxStack()),
	}
}

func (self *Frame) LocalVars() LocalVars {
	return self.localVars
}
func (self *Frame) OperandStack() *OperandStack {
	return self.operandStack
}
func (self *Frame) Thread() *Thread {
	return self.thread
}
func (self *Frame) NextPC() int {
	return self.nextPC
}
func (self *Frame) SetNextPC(nextPC int) {
	self.nextPC = nextPC
}
func (self *Frame) Method() *heap.Method {
	return self.method
}

// 复位指针，将指针重鑫指向当前指令
func (self *Frame) RevertNextPC() {
	self.nextPC = self.thread.pc
}

// 释放栈帧中所有引用类型的变量
func (self *Frame) Free() {
	// 释放局部变量表中的引用
	for i := range self.localVars {
		if ref := self.localVars.GetRef(uint(i)); ref != nil {
			//fmt.Printf("Releasing local var at index %d\n", i)
			ref.Release()
		}
	}
	// todo 操作数栈中的引用对象的计数释放
	//self.OperandStack().FreeStack()
}
